import os
import sys
import re
import urllib
from datetime import datetime
import logging
import wsgiref.handlers
from SimpleXMLRPCServer import SimpleXMLRPCDispatcher

from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template

sys.path = [os.path.dirname(__file__)] + sys.path

import AppEnv
import base.RequestHandler
import models.AppConfig
import models.Blog
import models.Comment
import models.Post
import models.Tag
import utils

def blogger_getUsersBlogs(discard, username, password):
    if not models.Blog.is_blogger(username):
        raise Exception('%s is not a blogger in this site.' % username)
    else:
        appconfig = models.AppConfig.getAppConfig()
        user = users.User(username)
        blogs = models.Blog.Blog.all().filter('owner = ', user).fetch(limit=1000)
        for blog in blogs:
            if blog.checkAPIPassword(username, password):
                return [{'url' : '%s%s/%s/' % (appconfig.HostURL, AppEnv.apppath, blog.blogId),
                 'blogid' : blog.blogId,
                 'blogName' : blog.blogName}]
        raise Exception('access denied')

def metaWeblog_newPost(blogid, username, password, article, publish):
    blog = models.Blog.get_blog(blogid)
    if not blog:
        raise Exception('blog %s does not exists.'%blogid)
    if not blog.checkAPIPassword(username, password):
        raise Exception('access denied')
        
    title = utils.toPageString(article['title'])
    content = utils.toPageString(article['description'])
                        
    cr = models.Post.checkAll(title,content)
    if not cr[0]:
        raise Exception('\n'.join(cr[1]))

    if article.has_key('categories'):
        tags = article['categories']
    else:
        tags = []
        
    uid = models.Post.new_post(blog = models.Blog.get_blog(blogid),
                        title = title,
                        content = content,
                        tags = tags,
                        publish=publish)
    return uid

def metaWeblog_editPost(postid, username, password, article, publish):
    posts = models.Post.Post.all().filter(' uid = ', postid).fetch(limit=1)

    if not posts:
        raise Exception('no this post(%s)' % postid)

    post = posts[0]
    blog = post.blog
    if not blog.checkAPIPassword(username, password):
        raise Exception('access denied')

    title = article['title']
    content = article['description']
                        
    cr = models.Post.checkAll(title,content)
    if not cr[0]:
        raise Exception('\n'.join(cr[1]))
    if article.has_key('categories'):
        tags = article['categories']
    else:
        tags = []

    models.Post.edit_post(blog = blog,
                   uid = postid,
                   title = title,
                   content = content,
                   tags = tags,
                   publish=publish)
    return True

def metaWeblog_getCategories(blogid, username, password):
    blog = models.Blog.get_blog(blogid)
    if not blog:
        raise Exception('blog %s does not exists.'%blogid)
    if not blog.checkAPIPassword(username, password):
        raise Exception('access denied')

    categories = []
    all_tags = models.Tag.Tag.all().filter('owner = ',models.Blog.get_blog(blogid))
    for tag in all_tags:
        categories.append({'description' : tag.name, 'title' : tag.name})

    return categories
    
def metaWeblog_getPost(postid, username, password):
    posts = models.Post.Post.all().filter(' uid = ', postid).fetch(limit=1)

    if not posts:
        raise Exception('no this post(%s)' % postid)

    post = posts[0]
    blog = post.blog
    if not blog.checkAPIPassword(username, password):
        raise Exception('access denied')


    return {
        'postid' : postid,
        'dateCreated' : post.date,
        'title' : post.title,
        'description' : unicode(post.content),
        'categories' : post.tags,
        'publish' : post.published,
        }

def metaWeblog_getRecentPosts(blogid, username, password, numberOfPosts):
    blog = models.Blog.get_blog(blogid)
    if not blog:
        raise Exception('blog %s does not exists.'%blogid)
    if not blog.checkAPIPassword(username, password):
        raise Exception('access denied')

    posts = models.Post.Post.all().filter('blog = ', blog).order('-date').fetch(min(numberOfPosts, blog.postsPerPage))
    result = []
    for post in posts:
        result.append({
            'postid' : post.uid,
            'dateCreated' : post.date,
            'title' : post.title,
            'description' : unicode(post.content),
            'categories' : post.tags,
            'publish' : post.published,
            })

    return result

def blogger_deletePost(appkey, postid, username, password, publish):
    posts = models.Post.Post.all().filter(' uid = ', postid).fetch(limit=1)

    if not posts:
        raise Exception('no this post(%s)' % postid)

    post = posts[0]
    blog = post.blog
    if not blog.checkAPIPassword(username, password):
        raise Exception('access denied')

    models.Post.delete_post(postid)
    return True

dispatcher = SimpleXMLRPCDispatcher(allow_none=True,encoding='UTF-8')
dispatcher.funcs = {
    'blogger.getUsersBlogs' : blogger_getUsersBlogs,
    'blogger.deletePost' : blogger_deletePost,
    'metaWeblog.newPost' : metaWeblog_newPost,
    'metaWeblog.editPost' : metaWeblog_editPost,
    'metaWeblog.getCategories' : metaWeblog_getCategories,
    'metaWeblog.getPost' : metaWeblog_getPost,
    'metaWeblog.getRecentPosts' : metaWeblog_getRecentPosts,
    }

dispatcher.register_introspection_functions()

class MetaWeblog(base.RequestHandler.RequestHandler):
    def get(self):        
        self.write('GET method is not supported, use POST instead please.')
        return
    def post(self):
        request = self.request.body
        #logging.error(request)
        response = dispatcher._marshaled_dispatch(request)
        #logging.error(response)
        self.write(response)
        return

def main():
    application = webapp.WSGIApplication(
                           [
                            (AppEnv.apppath + '/api/metaweblog', MetaWeblog),
                            ],
                           debug=AppEnv.debug)
    wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
    main()

